package com.quanyan.user.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.user.mapper.QuestionMapper;
import com.quanyan.user.mapper.TbQuestionAccessRecordMapper;
import com.quanyan.user.mapper.TbQuestionMapper;
import com.quanyan.user.mapper.TbQuestionSolveRecordMapper;
import com.quanyan.user.model.db.*;
import com.quanyan.user.model.vo.request.ReqQuestion;
import com.quanyan.user.model.vo.response.RespQuestion;
import com.quanyan.user.model.vo.response.RespQuestionCategory;
import com.quanyan.user.model.vo.response.RespQuestionDetail;
import com.quanyan.user.service.QuestionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by huadongyang on 2016/11/4.
 */
@Service
public class QuestionServiceImpl implements QuestionService {
    private static final Logger logger = LoggerFactory.getLogger(QuestionServiceImpl.class);

    @Autowired
    private TbQuestionMapper tbQuestionMapper;
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private TbQuestionAccessRecordMapper questionAccessRecordMapper;
    @Autowired
    private TbQuestionSolveRecordMapper questionSolveRecordMapper;

    @Override
    public APIResponse<PageObj<List<RespQuestion>>> queryQuestions(ReqQuestion reqQuestion) {
        List<RespQuestion> questions = null;
        int total;
        try {
            reqQuestion.setPageNo(reqQuestion.getPageNo() * reqQuestion.getPageSize());
            questions = questionMapper.queryQuestions(reqQuestion);
            total = questionMapper.questionCount(reqQuestion);
        } catch (Exception e) {
            logger.error("获取问题列表失败！:{}", e.getMessage());
            return APIResponse.returnFail("获取问题列表失败！");
        }
        return APIResponse.returnSuccess(PageObj.create(total, reqQuestion.getPageNo(), reqQuestion.getPageSize(), questions));
    }

    @Override
    public APIResponse<RespQuestionDetail> getQuestionDetail(Integer id) {
        RespQuestionDetail respQuestionDetail = new RespQuestionDetail();
        try {
            RespQuestion respQuestion = questionMapper.queryQuestion(id);
            respQuestionDetail.setRespQuestion(respQuestion);
            if (respQuestion != null && StringUtil.isNotBlank(respQuestion.getRelation())){
                List<RespQuestion> respQuestions = new ArrayList<>();
                for (String relation : respQuestion.getRelation().split(";")){
                    try {
                        Integer relationId  = Integer.parseInt(relation);
                        RespQuestion respRelationQuestion = questionMapper.queryQuestion(relationId);
                        if (respRelationQuestion != null){
                            respQuestions.add(respRelationQuestion);
                        }
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                        continue;
                    }
                }
                respQuestionDetail.setRelateQuestions(respQuestions);
            }
        } catch (Exception e) {
            logger.error("获取问题详情失败！：{}",e.getMessage());
            return APIResponse.returnFail("获取问题详情失败");
        }
        return APIResponse.returnSuccess(respQuestionDetail);
    }

    @Override
    public APIResponse<List<RespQuestionCategory>> queryQuestionCategories() {
        APIResponse<List<RespQuestionCategory>> apiResponse = null;
        try {
            List<RespQuestionCategory> respQuestionCategories = questionMapper.queryQuestionCategories();
            apiResponse = APIResponse.returnSuccess(respQuestionCategories);
        } catch (Exception e) {
            logger.error("获取问题分类列表失败！：{}", e.getMessage());
            return APIResponse.returnFail("获取问题分类列表失败!");
        }
        return apiResponse;
    }

    /**
     * @param id       问题ID
     * @param solve    0: 未解决 1：已解决
     * @param isCancel 是否取消 0：取消 1：选中
     * @param uid      用户id 可为空
     * @param ip       客户端访问接口的ip地址
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public APIResponse statsSolveQuestionNum(Integer id, Byte solve, Byte isCancel, Integer uid, String ip) {
        try {
            TbQuestionSolveRecordExample solveRecordExample = new TbQuestionSolveRecordExample();
            TbQuestionSolveRecordExample.Criteria questionSolveCriteria = solveRecordExample.createCriteria();
            questionSolveCriteria.andQuestionIdEqualTo(id);
            questionSolveCriteria.andIsDeleteEqualTo((byte) 0);
            if (uid == null || uid <= 0) {
                questionSolveCriteria.andIpEqualTo(ip);
            } else if (uid > 0) {
                questionSolveCriteria.andUidEqualTo(uid);
            }

            TbQuestionExample questionExample = new TbQuestionExample();
            TbQuestionExample.Criteria questionCriteria = questionExample.createCriteria();
            questionCriteria.andIdEqualTo(id);
            questionCriteria.andIsDeleteEqualTo((byte)0);
            questionCriteria.andStatusEqualTo((byte)1);
            List<TbQuestion> tbQuestions = tbQuestionMapper.selectByExample(questionExample);

            int solved = 0;
            int unsolved = 0;

            if (tbQuestions == null || tbQuestions.size() == 0) {
                return APIResponse.returnFail("没有对应问题");
            }

            solved = tbQuestions.get(0).getSolve();
            unsolved = tbQuestions.get(0).getUnsolved();

            if (isCancel.byteValue() == 0 ) {  //取消状态
                questionSolveCriteria.andSolveStatusEqualTo(solve);
                int recordCount = questionSolveRecordMapper.countByExample(solveRecordExample);   //获取问题解决和为解决记录
                if (recordCount > 0 ) {
                    //更新操作
                    TbQuestionSolveRecord solveRecord = new TbQuestionSolveRecord();
                    solveRecord.setIsDelete((byte) 1);
                    int ret = questionSolveRecordMapper.updateByExampleSelective(solveRecord, solveRecordExample);

                    if (ret > 0 ) {
                        if (solve.byteValue() == 0 && unsolved > 0) {  //未解决
                            questionMapper.subtractSolveQuestionNum(id, solve);
                        }
                        if (solve.byteValue() == 1 && solved > 0) {    //已解决
                            questionMapper.subtractSolveQuestionNum(id, solve);
                        }
                    }
                }

            } else if (isCancel.byteValue() == 1 ) {  //选中状态
                int recordCount = questionSolveRecordMapper.countByExample(solveRecordExample);   //获取问题解决和未解决记录
                if (recordCount <= 0 && (solve.byteValue() == 0 || solve.byteValue() == 1)) {     // 没有问题记录
                    addQuestionSolvedNum(id, solve, uid, ip);
                }else {
                    //更新操作
                    TbQuestionSolveRecord solveRecord = new TbQuestionSolveRecord();
                    solveRecord.setIsDelete((byte) 1);
                    int ret = questionSolveRecordMapper.updateByExampleSelective(solveRecord, solveRecordExample);
                    if (ret > 0) {
                        byte notSolve = 0;
                        if (solve.byteValue() == 0) {
                            notSolve = 1;
                        }
                        if (solve.byteValue() == 1) {
                            notSolve = 0;
                        }
                        if (notSolve == 0 && unsolved > 0) {  //未解决
                            int subResult = questionMapper.subtractSolveQuestionNum(id, notSolve);
                            if (subResult > 0) {
                                addQuestionSolvedNum(id, solve, uid, ip);
                            }
                        }
                        if (notSolve == 1 && solved > 0) {    //已解决
                            int subResult = questionMapper.subtractSolveQuestionNum(id, notSolve);
                            if (subResult > 0) {
                                addQuestionSolvedNum(id, solve, uid, ip);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("更新问题解决数失败！:{}", e.getMessage());
            return APIResponse.returnFail("更新问题解决数失败!");
        }

        return APIResponse.returnSuccess();
    }

    /**
     * 增加问题解决数
     * @param id
     * @param solve
     * @param uid
     * @param ip
     */
    private void addQuestionSolvedNum(Integer id, Byte solve, Integer uid, String ip) {
        int result = questionMapper.addSolveQuestionNum(id, solve);
        if (result > 0) {
            TbQuestionSolveRecord questionSolveRecord = new TbQuestionSolveRecord();
            if (uid == null || uid <= 0) {
                questionSolveRecord.setIp(ip);
            }
            questionSolveRecord.setQuestionId(id);
            questionSolveRecord.setSolveStatus(solve);
            questionSolveRecord.setUid(uid);
            questionSolveRecordMapper.insertSelective(questionSolveRecord);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public APIResponse statsQuestionPVandUV(Integer id, Integer uid, String ip) {
        try {
            //统计pv
            TbQuestionAccessRecordExample recordExample = new TbQuestionAccessRecordExample();
            TbQuestionAccessRecordExample.Criteria criteria = recordExample.createCriteria();
            criteria.andQuestionIdEqualTo(id);
            if (uid == null || uid <= 0) {
                criteria.andIpEqualTo(ip);
            } else if (uid > 0) {
                criteria.andUidEqualTo(uid);
            }
            int recordCount = questionAccessRecordMapper.countByExample(recordExample);
            if (recordCount > 0) {  //已经统计了uv
                questionMapper.statsQuestionPVandUV(id, (byte) 1);  //统计pv
            } else {   //未统计uv
                questionMapper.statsQuestionPVandUV(id, (byte) 2);  //统计pv和uv
                TbQuestionAccessRecord questionAccessRecord = new TbQuestionAccessRecord();
                questionAccessRecord.setUid(uid);
                if (uid == null || uid <=0) {
                    questionAccessRecord.setIp(ip);
                }
                questionAccessRecord.setQuestionId(id);
                questionAccessRecordMapper.insertSelective(questionAccessRecord);
            }
        } catch (Exception e) {
            logger.error("统计pv和uv失败：{}", e.getMessage());
            return APIResponse.returnFail("统计pv和uv失败");
        }

        return APIResponse.returnSuccess();
    }
}
